from pyasn1.type import univ, namedtype, tag, constraint
from pyasn1.type import char  # 导入字符类型模块

# 1. 自定义序列类型
class Person(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('name', char.PrintableString()),  # 修正：从 char 模块导入
        namedtype.NamedType('age', univ.Integer()),
        namedtype.OptionalNamedType('address', char.PrintableString())  # 修正：从 char 模块导入
    )


# 3. 自定义选择类型
class ContactInfo(univ.Choice):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('phone', char.PrintableString()),  # 修正：从 char 模块导入
        namedtype.NamedType('email', char.IA5String()),  # 修正：从 char 模块导入
        namedtype.NamedType('address', char.PrintableString())  # 修正：从 char 模块导入
    )

# 4. 自定义集合类型
class AddressBook(univ.Set):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('owner', char.PrintableString()),  # 修正：从 char 模块导入
        namedtype.NamedType('contacts', univ.SequenceOf(componentType=Person()))
    )

# 5. 自定义带有扩展标记的类型
class ExtensiblePerson(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('name', char.PrintableString()),  # 修正：从 char 模块导入
        namedtype.NamedType('age', univ.Integer()),
        # 扩展标记
        namedtype.OptionalNamedType(
            'extension',
            univ.Any().subtype(
                implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
            )
        )
    )

# 使用示例
person = Person()
person['name'] = 'John Doe'
person['age'] = 30
person['address'] = '123 Main St'

contact = ContactInfo()
contact['email'] = 'john@example.com'

# 构造 AddressBook 实例
address_book = AddressBook()

# 设置所有者
address_book['owner'] = 'Alice'

# 创建联系人
contact1 = Person()
contact1['name'] = 'John Doe'
contact1['age'] = 30
contact1['address'] = '123 Main St'

contact2 = Person()
contact2['name'] = 'Jane Smith'
contact2['age'] = 25
contact2['address'] = '456 Elm St'

# 将联系人添加到联系人列表中
address_book['contacts'].extend([contact1, contact2])

# 打印 AddressBook 实例
print(address_book.prettyPrint())

ext_person = ExtensiblePerson()
ext_person['name'] = 'Jane Smith'
ext_person['age'] = 25
ext_person['extension'] = b'\x01\x02\x03'
ext_person['extension'] = 123
ext_person['extension'] = 'abc'
# 方法 2：使用 OctetString 并转换为 Any
# octet_data = univ.OctetString(b'\x01\x02\x03')
# any_data = univ.Any()
# any_data.fromOctetString(encoder.encode(octet_data))
# ext_person['extension'] = any_data